module CublasFortran
    use ::lapack95
    use :: blas95
    !$ use omp_lib 
implicit none

	contains
    SUBROUTINE gemvGPU(A,x,y,matrixSize)
        integer:: matrixSize
        REAL(kind=8):: A(matrixSize,matrixSize)
        integer :: size_of_real=8 !4->single precision; 8->double precision
        integer(8) :: devPtrA, devPtrB, devPtrC

        
       
         !ALLOC MEMORY
          call cublas_alloc(matrixSize*matrixSize, size_of_real, devPtrA)
         call cublas_alloc(matrixSize, size_of_real, devPtrB)
         call cublas_alloc(matrixSize, size_of_real, devPtrC)
        !set vars
        call cublas_set_matrix(matrixSize,matrixSize,size_of_real,A,matrixSize,devPtrA,matrixSize)
        call cublas_set_vector(matrixSize,size_of_real,x,1,devPtrB,1)
        call cublas_set_vector(matrixSize,size_of_real,y,1,devPtrC,1)
       !calculate
        call cublas_dgemv('N',matrixSize,matrixSize,1,devPtrA,matrixSize,devPtrB,1,1,devPtrC,1)
         ! get back
        call cublas_get_vector(matrixSize,size_of_real,y,1,devPtrC,1)
     
    !Free GPU memory
        call cublas_free(devPtrA)
        call cublas_free(devPtrB)
        call cublas_free(devPtrC)
         
         

     end subroutine 
   


end module
